TypeScript 50.6%
JavaScript 46.1%
SQL 2.1%
Shell 0.6%
CSS 0.5%
1import { NextRequest, NextResponse } from "next/server";2import { assertSameOrigin, currentUser, requireUser } from "@/lib/auth/session";3import { getListingFull, updateListing, deleteDraft, ConflictError, assertOwner } from "@/lib/listings/service";4import { ListingInput, publishProblems } from "@/lib/listings/types";5import { mediaUrl } from "@/lib/listings/media";6import { apiError, handle, parseBody } from "@/lib/api";7export const dynamic = "force-dynamic";8type P = { params: Promise<{ id: string }> };9export async function GET(_req: NextRequest, { params }: P) {10 try {11 const { id } = await params; const l = await getListingFull(id); if (!l) return apiError(404, "not_found", "Annonce introuvable");12 const u = await currentUser(); const isOwner = !!u && (l.ownerUserId === u.id || u.roles.includes("ADMIN") || u.roles.includes("MODERATOR"));13 if (l.status !== "PUBLISHED" && !isOwner) return apiError(404, "not_found", "Annonce introuvable");14 const media = l.media.map((m) => ({ id: m.id, url: mediaUrl(m.storageKey, 800), large: mediaUrl(m.storageKey, 1600), thumb: mediaUrl(m.storageKey, 320), position: m.position, altText: m.altText, width: m.width, height: m.height }));15 const problems = isOwner ? publishProblems({ listingType: l.listingType, propertyType: l.property.propertyType, priceAmount: l.priceAmount, title: l.title, description: l.description, city: l.property.city, lat: l.property.lat, mediaCount: l.media.length, attestedAt: l.attestedAt, bedrooms: l.property.bedrooms, areaSqft: l.property.areaSqft }) : undefined;16 return NextResponse.json({ listing: { ...l, media, ownerUserId: isOwner ? l.ownerUserId : undefined, problems } });17 } catch (e) { return handle(e); }18}19export async function PATCH(req: NextRequest, { params }: P) {20 try { await assertSameOrigin(); const u = await requireUser(); const { id } = await params; const input = await parseBody(req, ListingInput); const l = await updateListing(id, u.id, u.roles, input); return NextResponse.json({ listing: l }); }21 catch (e) { if (e instanceof ConflictError) return apiError(409, "conflict", e.message); return handle(e); }22}23export async function DELETE(_req: NextRequest, { params }: P) { try { await assertSameOrigin(); const u = await requireUser(); const { id } = await params; const l = await getListingFull(id); if (l) assertOwner(l, u.id, u.roles); await deleteDraft(id, u.id, u.roles); return NextResponse.json({ ok: true }); } catch (e) { return handle(e); } }24